<?php

declare(strict_types=1);

namespace App\WorkDepartment\Logic;

use Hyperf\Contract\StdoutLoggerInterface;
use App\Corp\Service\CorpService;
use App\WorkDepartment\Service\WorkDepartmentService;
use Base\WeWork\WeWork;

/**
 * 部门管理-同步.
 *
 * Class SynLogic
 */
class SyncLogic
{
    use DepartmentTrait;

    /**
     * @var WeWork
     */
    protected $client;

    /**
     * @var WorkDepartmentService
     */
    protected $workDepartmentService;

    /**
     * @var CorpService
     */
    protected $corpService;

    /**
     * @var StdoutLoggerInterface
     */
    protected $logger;

    public function handle(array $corpIds, array $params): array
    {
        try {
            $this->logger = make(StdoutLoggerInterface::class);
            if (empty($corpIds)) {
                $this->logger->error('WorkDepartmentSynLogic->handle同步部门corpId不能为空');
                return [];
            }
            $this->client = make(WeWork::class);
            $this->workDepartmentService = make(WorkDepartmentService::class);
            $corpData = $this->getCorpData($corpIds);
            if (empty($corpData)) {
                $this->logger->error('WorkDepartmentSynLogic->handle同步部门corp不能为空');
                return [];
            }
            if(!empty($corpData)) {
                foreach ($corpData as $corpId => $cdv) {
                    $wxDepartment = $this->client->provider('user')->app($cdv)->department->list();
                    if (empty($wxDepartment['errcode']) && $wxDepartment['department']) {
                        //获取部门ID
                        $department = $this->getDepartmentIds($cdv['save_corp_id']);
                        $result=array_diff_key(array_column($wxDepartment['department'],null,'id'),$department);
                        $this->logger->info('部门对比异同',(array)$result);
                        if(empty($result)) continue;
                        foreach ($wxDepartment['department'] as $key => $value) {
                            if (empty($department[$value['id']])) {
                                $createData[] = [
                                    'wx_department_id' => $value['id'],
                                    'corp_id' => $cdv['save_corp_id'],
                                    'tenant_id' => $params['tenantId'],
                                    'name' => $value['name'],
                                    'wx_parentid' => $value['parentid'],
                                    'parent_id' => $value['parentid'],
                                    'order' => $value['order'],
                                    'create_time' => date('Y-m-d H:i:s'),
                                ];
                            } else if($department[$value['id']]['name']!=$value['name']){
                                //部门名称修改
                                $oldDataupdate = [
                                    'name' => $value['name'],
                                    'update_time' => date('Y-m-d H:i:s'),
                                ];
                                $this->workDepartmentService->updateWorkDepartmentById($department[$value['id']]['id'],$oldDataupdate);
                                unset($oldDataupdate);
                            }else if($department[$value['id']]['wxParentid']!=$value['parentid']){
                                //部门上级修改
                                $oldDataupdate = [
                                    'id' => $department[$value['id']]['id'],
                                    'wx_parentid' => $value['parentid'],
                                    'parent_id' => $value['parentid'],
                                    'update_time' => date('Y-m-d H:i:s'),
                                ];
                                $parentDepartment = $this->getDepartmentIds($cdv['save_corp_id']);
                                $department[$value['id']]['wxParentid'] = $value['parentid'];
                                $relation = $this->getDepartmentRelation($department[$value['id']], $parentDepartment);
                                if(!empty($relation['path']))$oldDataupdate['path'] = $relation['path'];
                                if(!empty($relation['level']))$oldDataupdate['level'] = $relation['level'];
                                $this->workDepartmentService->updateWorkDepartmentById($department[$value['id']]['id'],$oldDataupdate);
                                unset($oldDataupdate);
                            }
                        }
                        if (!empty($createData)) {
                            $createChunkData = array_chunk($createData, 100);
                            foreach ($createChunkData as $newCreateData) {
                                //创建部门
                                $result = $this->workDepartmentService->createWorkDepartments($newCreateData);
                                if ($result) {
                                    //处理父部门
                                    $parentDepartment = $this->getDepartmentIds($cdv['save_corp_id']);
                                    $updateData = $this->getDepartmentUpdateData($parentDepartment);
                                    if (!empty($updateData)) {
                                        $updateResult = $this->workDepartmentService->updateWorkDepartmentByIds($updateData);
                                        if (empty($updateResult)) {
                                            $this->logger->error('WorkDepartmentSynLogic->handle同步部门失败');
                                            return [];
                                        }
                                    }
                                }
                            }
                        }
                    }
                    unset($wxDepartment, $createChunkData, $createData, $result, $parentDepartment, $updateData);
                }
            }
        }catch (\Exception $e){
            $this->logger->error('handle同步部门报错'.$e->getMessage().'|||');
            $this->logger->error($e->getTraceAsString());
        }
    }

    /**
     * 获取部门ID.
     * @param $corpId
     * @return array
     */
    private function getDepartmentIds($corpId)
    {
        $department = [];
        $departmentData = $this->workDepartmentService->getWorkDepartmentsByCorpId($corpId);
        array_map(function ($item) use (&$department) {
            $department[$item['wxDepartmentId']] = $item;
        }, $departmentData);
        return $department;
    }

    /**
     * 获取公司信息.
     * @return array
     */
    private function getCorpData(array $corpIds)
    {
        $this->corpService = make(CorpService::class);
        $corpData = $this->corpService->getCorpsByCorpIds($corpIds, ['corp_id','wx_corpid', 'employee_secret', 'id']);
        if (empty($corpData)) {
            return [];
        }
        foreach ($corpData as $cdk => $cdv) {
            if($cdk>0){
                if($corpData[$cdk-1]['wxCorpid']==$cdv['wxCorpid']&&$corpData[$cdk-1]['employeeSecret']==$cdv['employeeSecret']){
                    continue;
                }
            }
            $corp[$cdv['id']] = [
                'corp_id' => $cdv['wxCorpid'],
                'save_corp_id' => $cdv['corpId'],
                'secret' => $cdv['employeeSecret'],
            ];
        }
        return $corp??[];
    }

    /**
     * 更新部门数据.
     * @param $parentDepartment
     * @return array
     */
    private function getDepartmentUpdateData($parentDepartment)
    {
        $updateData = [];
        array_map(function ($item) use (&$updateData, $parentDepartment) {
            //级别
            $relation = $this->getDepartmentRelation($item, $parentDepartment);
            $updateData[] = [
                'id' => $item['id'],
                'update_time' => date('Y-m-d H:i:s'),
                'path' => $relation['path'],
                'level' => $relation['level'],
                'parent_id' => ! empty($parentDepartment[$item['wxParentid']]) ? $parentDepartment[$item['wxParentid']]['id'] : 0,
            ];
        }, $parentDepartment);
        return $updateData;
    }
}
